#pragma once
#include <memory>
#include <string>
#include <cstddef>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <odb/nullable.hxx>
#include <odb/core.hxx>

namespace UserFields {
    constexpr const char* ID = "userId";
    constexpr const char* NICKNAME = "nickname";
    constexpr const char* PHONE = "phone";
    constexpr const char* DESCRIPTION = "description";
    constexpr const char* AVATAR_ID = "avatarId";
    
    constexpr const char* ID_KEYWORD = "userId.keyword";
    constexpr const char* PHONE_KEYWORD = "phone.keyword";
    constexpr const char* AVATAR_ID_KEYWORD = "avatarId.keyword";
}

namespace entity {

#pragma db object table("user")
class User 
{
public:
    User() {}
    User(const std::string& uid, const std::string& passwd, 
        const std::string& nickname, const std::string& phone)
        : userId_(uid), password_(passwd), nickname_(nickname), phone_(phone) {}

    void setUserId(const std::string& val) { userId_ = val; }
    std::string userId() { return userId_; }

    void setNickname(const std::string& val) { nickname_ = val; }
    std::string nickname() { return nickname_; }

    void setPassword(const std::string& val) { password_ = val; }
    std::string password() { return password_; }

    void setPhone(const std::string& val) { phone_ = val; }
    std::string phone() { return phone_; }

    void setDscription(const std::string& val) { description_ = val; }
    std::string description() { return description_ ? *description_ : std::string(); }

    void setAvatarId(const std::string& val) { avatarId_ = val; }
    std::string avatarId() { return avatarId_ ? *avatarId_ : std::string(); }

private:
    friend class odb::access; 
    
    #pragma db id auto
    uint32_t id_;

    #pragma db column("user_id") type("varchar(32)") index unique
    std::string userId_;

    #pragma db type("varchar(32)") index unique
    std::string nickname_;

    #pragma db type("varchar(32)") index unique
    std::string password_;

    #pragma db type("char(16)") index unique
    std::string phone_; 

    #pragma db type("varchar(64)")
    odb::nullable<std::string> description_;

    #pragma db type("varchar(64)")
    odb::nullable<std::string> avatarId_;
};

using UserPtr = std::shared_ptr<User>;

}

// odb -d mysql --std c++11 --generate-query --generate-schema --profile boost/date-time user.hxx